﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using WinFormClient.ServiceReference1;

namespace WinFormClient
{
    //暂时可以不用这个详细结果信息，直接函数int返回就可以，0=成功 -1=失败
    public enum RESULTINFO
    {
        SUCCESS = 0,
        NETERROR = -1,
        EMPTY = -2
    };

    public class ClientDataCenter : WinFormClient.IDataHandler
    {
        public ClientData data;
        SmallBoneServiceSoapClient connection = new SmallBoneServiceSoapClient();

        //里面的代码用于从本地文件读取 data 对象;
        public ClientDataCenter()
        {
            if (data == null)
            {
                Stream stream = new FileStream("LocalStorage.dat", FileMode.OpenOrCreate,
                    FileAccess.Read, FileShare.None);
                try
                {
                    IFormatter formatter = new BinaryFormatter();
                    data = (ClientData)formatter.Deserialize(stream);
                    data.userID2name = new Dictionary<int, string>();
                }
                catch (Exception ex)
                {
                    data = new ClientData();
                    data.userID2name = new Dictionary<int, string>();
                }
                finally { stream.Close(); }
            }
        }

        //样例代码
        public LoginState TryLogin(out RESULTINFO result)
        {
            result = RESULTINFO.SUCCESS;
            try
            {
                ServiceReference1.LoginState tmp = connection.LogIn(data.userinfo.UserName, data.userinfo.Password, "", DateTime.Now);
                if (tmp == LoginState.LOGIN)
                {
                     userid id = connection.UsernameToUserid(data.userinfo.UserName);
                     if (id.Exist && !id.DbError) data.userinfo.UserID = id.Userid;
                }
                return tmp;
            }
            catch(Exception ex)
            {
                throw ex;
                return ServiceReference1.LoginState.DBERROR;
            }
        }

        
        public int TryGetGroups(out GroupSet groups, out RESULTINFO result)
        {
            result = RESULTINFO.SUCCESS;
            try
            {
                groups = connection.GetGroups(0, 1000, SortForm.DEFAULT);
                return 0;
            }
            catch
            {
                groups = new GroupSet();
                return -1;
            }
        }

        public int TryGetTopics(int groupid, int startposition, int endposition, out TopicSet topics, out RESULTINFO result)
        {
            result = RESULTINFO.SUCCESS;
            try
            {
                topics = connection.GetTopics(startposition, endposition, groupid, SortForm.DEFAULT);
                return 0;
            }
            catch(Exception ex)
            {
                throw ex;
                topics = new TopicSet();
                return -1;
            }
        }

        public int TryGetMessages(int topicid, int start, int end, SortForm sortform, out MessageSet msgs, out RESULTINFO result)
        {
            result = RESULTINFO.SUCCESS;
            //try
            //{
                msgs = connection.GetReplies(start, end, topicid, sortform);
                foreach (Message m in msgs.Messages)
                {
                    if (!data.userID2name.ContainsKey(m.userId)){
                        username u = connection.UseridToUsername(m.userId);
                        if (u.Exist && (!u.DbError)) data.userID2name.Add(m.userId, u.Username);
                        else data.userID2name.Add(m.userId, "没名字");
                    }
                    string name; data.userID2name.TryGetValue(m.userId,out name);
                    m.userName = name;
                }
                return 0;
            //}
            //catch(Exception ex)
            //{
            //    throw ex;
            //    msgs = new MessageSet();
            //    return -1;
            //}
        }

        public int TryAddMesseage(Message msg, out RESULTINFO result)
        {
            result = RESULTINFO.SUCCESS;
            try
            {
                connection.CommitReply(data.userinfo.UserID, msg.content, msg.topicId);
                return 0;
            }
            catch
            {
                return -1;
            }
        }

        public CreateState TryAddTopic(Topic topic, out RESULTINFO result)
        {
            result = RESULTINFO.SUCCESS;
            try
            {
                CreateResult r = connection.NewTopic(data.userinfo.UserID, topic.title, topic.groupId);
                return r.createState;
            }
            catch(Exception ex)
            {
                throw ex;
                return CreateState.ERROR_WHILE_READ_DB;
            }
        }

        public AssignState TrySignUp(out RESULTINFO result)
        {
            result = RESULTINFO.SUCCESS;
            try
            {
                AssignResult tmp=connection.DBSignIn(data.userinfo.UserName, data.userinfo.Password);
                return tmp.assignState;
            }
            catch(Exception ex)
            {
                throw ex;
                //return AssignState.ERROR_WHILE_READ_DB;
            }            
        }

        public int TryLogout(out RESULTINFO result)
        {
            result = RESULTINFO.SUCCESS;
            try
            {
                connection.LogOut(data.userinfo.UserName, "", DateTime.Now);
                return 0;
            }
            catch
            {
                return -1;
            }
        }

        //用于本地保存 在client.Exit()里面已经调用
        public void LocalSave()
        {
            try
            {
                IFormatter formatter = new BinaryFormatter();
                Stream stream = new FileStream("LocalStorage.dat", FileMode.Create,
                FileAccess.Write, FileShare.None);
                formatter.Serialize(stream, data);
                stream.Close();
            }
            catch (System.Exception ex)
            {
                throw ex;
            }            
        }
    }
}
